#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project : aimix
@File    : processor.py
@IDE     : PyCharm
@Author  : admin
@Date    : 2025/4/7 14:08
"""
import concurrent.futures
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed


from core.video.single_video_process_method import *
from log import log




def batch_set_srt_to_video(tasks, srt_path, outfile_path, bottom_margin, font_path, font_size, font_color, horizontal_margin, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=outfile_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_srt_to_video,
                    task,
                    srt_path,
                    outfile,
                    bottom_margin,
                    font_path,
                    font_size,
                    font_color,
                    horizontal_margin
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_set_subtitle_to_video(tasks, subtitle_text, outfile_path, bottom_margin, font_path, font_size, font_color, subtitle_duration, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=outfile_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_subtitle_to_video,
                    task,
                    outfile,
                    subtitle_text,
                    bottom_margin,
                    font_path,
                    font_size,
                    font_color,
                    subtitle_duration
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_set_background_music_to_video(tasks, audio_path, outfile_path, volume, keep_original_audio, video_priority, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=outfile_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_background_music_to_video,
                    task,
                    audio_path,
                    outfile,
                    volume,
                    keep_original_audio,
                    video_priority
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_set_image_overlay_to_video(tasks, image_path, output_path, overlay_duration, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=output_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_image_overlay_to_video,
                    task,
                    image_path,
                    outfile,
                    overlay_duration
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_set_video_cover(tasks, cover_path, output_path, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=output_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_video_cover,
                    task,
                    cover_path,
                    outfile
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_set_text_watermark_to_video(tasks, watermark_text, output_path, x, y, font_path, font_size, font_color, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in tasks:
            outfile = tempfile.mktemp(suffix=".mp4", dir=output_path)
            res.append(outfile)
            futures.append(
                executor.submit(
                    set_text_watermark_to_video,
                    task,
                    outfile,
                    watermark_text,
                    x,
                    y,
                    font_path,
                    font_size,
                    font_color
                )
            )
        for future in as_completed(futures):
            future.result()
        return res


def batch_clip_video(tasks: list, output_path: str, start_time, end_time, max_workers: int =4) -> list:
    """
    并行处理多个视频剪辑任务。
    :param tasks: 任务列表，每个元素是 (input_file, output_file, start_time, end_time)

    :param max_workers: 最大并发线程数
    """
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_task = []
        res = []
        for task in tasks:
            output_file = tempfile.mktemp(suffix=".mp4", dir=output_path)
            res.append(output_file)
            future_to_task.append(executor.submit(clip_video_by_moviepy, task, output_file, start_time, end_time))
        for future in as_completed(future_to_task):
            future.result()
        return res


def batch_speed_up_videos(video_paths: List[str], output_dir: str, factor: float, keep_original_audio: bool = True, max_workers: int = 5):
    """
        批量给视频和音频加速，音频保持原音色，可选是否保留原声音。
    :param video_paths: 视频文件路径列表
    :param output_dir: 输出目录
    :param factor: 加速因子
    :param keep_original_audio: 是否保留并加速原始音频
    :param max_workers: 最大线程数
    """
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)
    result = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        for path in video_paths:
            if not os.path.exists(path):
                log.debug(f"跳过不存在的文件: {path}")
                continue
            output_path = output_dir / Path(path).name
            result.append(output_path)
            futures.append(executor.submit(speed_up_video_with_audio, path, str(output_path), factor, keep_original_audio))

        for future in as_completed(futures):
            future.result()  # 捕获异常
    return result


def batch_resize_videos(video_paths: List[str], output_dir: str, resolution: tuple = (720, 1280), max_workers: int = 5):
    """
        批量调整视频分辨率
    """
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        res = []
        for task in video_paths:
            if not os.path.exists(task):
                log.debug(f"跳过不存在的文件: {task}")
                continue
            output_file = tempfile.mktemp(suffix=".mp4", dir=output_dir)
            res.append(output_file)
            futures.append(executor.submit(resize_video, task, output_file, resolution))

        for future in as_completed(futures):
            log.debug(future.__dict__)
            future.result()  # 捕获异常
        return res


def batch_merge_videos(video_groups: List[List[str]], output_dir: str, keep_audio: bool = True, with_transition: bool = False, transition_duration: float = 0.4, max_workers: int = 5):
    """
        批量合并多个视频文件为一个视频文件
    :param video_groups: 视频文件路径列表
    :param output_dir: 输出目录
    :param keep_audio: 是否保留音频
    :param with_transition: 是否添加淡入淡出效果
    :param transition_duration: 淡入淡出持续时间
    :param max_workers: 最大线程数
    """
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        for group in video_groups:
            if not group:
                continue
            output_path = tempfile.mktemp(suffix='.mp4', dir=output_dir)
            futures.append(executor.submit(merge_videos, group, str(output_path), keep_audio, with_transition, transition_duration))
        res = [future.result() for future in as_completed(futures)]
        return res


